package com.hyt.it.ogt.ks.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hyt.it.ogt.ks.enums.PaperItemAttrTypeCode;
import com.hyt.it.ogt.ks.enums.PaperItemTypeCode;
import com.hyt.it.ogt.ks.enums.PaperTypeCode;
import com.hyt.it.ogt.ks.feign.model.ItemDataVO;
import com.hyt.it.ogt.ks.feign.model.OptionsDataVO;
import com.hyt.it.ogt.ks.feign.model.PaperDataVO;
import com.hyt.it.ogt.ks.feign.model.TopicDataVO;
import com.hyt.it.ogt.ks.model.entity.CandidateAnswer;
import com.hyt.it.ogt.ks.model.entity.CandidateAnswerBackup;
import com.hyt.it.ogt.ks.model.entity.CandidatePaper;
import com.hyt.it.ogt.ks.model.entity.CandidateProcess;
import com.hyt.it.ogt.ks.model.vo.ItemAttrDTO;
import com.hyt.it.ogt.ks.service.ICandidateAnswerBackupService;
import com.hyt.it.ogt.ks.service.ICandidateAnswerService;
import com.hyt.it.ogt.ks.service.ICandidatePaperService;
import com.hyt.it.ogt.ks.service.ICandidateProcessService;
import com.hyt.it.ogt.ks.service.IExamCacheService;
import com.hyt.it.ogt.ks.service.IScoreService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ScoreServiceImpl implements IScoreService {
    @Resource
    private ICandidateProcessService iCandidateProcessService;
    @Resource
    private ICandidateAnswerService iCandidateAnswerService;
    @Resource
    private ICandidateAnswerBackupService iCandidateAnswerBackupService;
    @Resource
    private ICandidatePaperService iCandidatePaperService;
    @Resource
    private IExamCacheService iExamCacheService;

/*
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void calcScoreByCandidate(String examId, String candidateId, boolean isBackup, Map<String, String> map) {
        List<CandidatePaper> list = iCandidatePaperService.lambdaQuery()
                .select(CandidatePaper::getId, CandidatePaper::getPaperId, CandidatePaper::getPaperVersion)
                .eq(CandidatePaper::getExamId, examId)
                .eq(CandidatePaper::getCandidateId, candidateId).list();
        log.info("单个考生开始统分：{}、{}、{}、{}", examId, candidateId, isBackup, map);
        if (!list.isEmpty()) {
            BigDecimal totalScore = BigDecimal.ZERO;
            for (CandidatePaper paper : list) {
                String paperId = paper.getPaperId();
                String paperVersion = paper.getPaperVersion();
                if (StringUtils.isNotBlank(paperId)) {
                    List<CandidateAnswer> ansUpdateList = new ArrayList<>();
                    List<CandidateAnswerBackup> backAnsUpdateList = new ArrayList<>();
                    List<CandidateAnswer> candidateAnswerList = null;

                    if (isBackup) {
                        candidateAnswerList = iCandidateAnswerBackupService.calculateAllStudentScores(examId, candidateId, paperId, paperVersion);
                    } else {
                        candidateAnswerList = iCandidateAnswerService.lambdaQuery().select(CandidateAnswer::getItemId, CandidateAnswer::getObjectiveAnswer,
                                        CandidateAnswer::getId)
                                .eq(CandidateAnswer::getExamId, examId).eq(CandidateAnswer::getCandidateId, candidateId)
                                .eq(CandidateAnswer::getPaperId, paperId).eq(CandidateAnswer::getPaperVersion, paperVersion)
                                .eq(CandidateAnswer::getDelFlag, false).list();
                    }

                    candidateAnswerList.stream().forEach(candidateAnswer -> {
                        String k = StringUtils.join(examId, "_", paperId, "_", paperVersion, "_", candidateAnswer.getItemId(), "_");
                        String key_answer = StringUtils.join(k, "answer");
                        String key_score = StringUtils.join(k, "score");
                        String standardAnswer = map.get(key_answer);
                        if (standardAnswer != null) {
                            String answer = candidateAnswer.getObjectiveAnswer();
                            BigDecimal score = BigDecimal.ZERO;
                            if (StringUtils.isNotBlank(answer) && answer.equals(standardAnswer)) {
                                score = new BigDecimal(String.valueOf(map.get(key_score)));
                            }
                            if (isBackup) {
                                CandidateAnswerBackup en = new CandidateAnswerBackup();
                                en.setId(candidateAnswer.getId());
                                en.setScore(score);
                                en.setStandardAnswer(standardAnswer);
                                backAnsUpdateList.add(en);
                            } else {
                                CandidateAnswer en = new CandidateAnswer();
                                en.setScore(score);
                                en.setId(candidateAnswer.getId());
                                en.setStandardAnswer(standardAnswer);
                                ansUpdateList.add(en);
                            }
                            candidateAnswer.setScore(score);
                        }
                    });
                    BigDecimal currentScore = totalScore.add(candidateAnswerList.stream()
                            .map(c -> c.getScore() == null ? BigDecimal.ZERO : c.getScore())
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    totalScore = totalScore.add(currentScore);

                    iCandidatePaperService.lambdaUpdate().eq(CandidatePaper::getId, paper.getId())
                            .set(CandidatePaper::getObjectiveScore, currentScore).update();

                    if (ansUpdateList.size() > 0) {
                        iCandidateAnswerService.updateBatchById(ansUpdateList);
                    }
                    if (backAnsUpdateList.size() > 0) {
                        iCandidateAnswerBackupService.updateBatchById(backAnsUpdateList);
                    }
                }
            }
            //客观题分数入库
            iCandidateProcessService.lambdaUpdate().eq(CandidateProcess::getExamId, examId)
                    .eq(CandidateProcess::getCandidateId, candidateId).set(CandidateProcess::getObjectiveScore, totalScore)
                    .update();
        }
    }

 */

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void calcScoreByCandidate(String examId, String candidateId, List<PaperDataVO> paperDataList, boolean isBackup) {
        QueryWrapper<CandidatePaper> queryCandidatePaper = Wrappers.query();
        queryCandidatePaper.lambda().select(CandidatePaper::getId, CandidatePaper::getPaperId, CandidatePaper::getPaperVersion)
                .eq(CandidatePaper::getExamId, examId)
                .eq(CandidatePaper::getCandidateId, candidateId)
                .eq(CandidatePaper::getPaperType, PaperTypeCode.NORMAL.getCode());
        List<CandidatePaper> candidatePaperList = iCandidatePaperService.list(queryCandidatePaper);
        //答案表统分
        this.calcObjectiveCandidateAnswerList(examId, candidateId, candidatePaperList, paperDataList, isBackup ? 1 : 0);
        //试卷表统分
        candidatePaperList.forEach(c -> {
            BigDecimal paperScore = this.getCandidatePaperObjectScore(examId, candidateId, c.getPaperId(), c.getPaperVersion(), isBackup ? 1 : 0);
            c.setObjectiveScore(paperScore);
        });
        iCandidatePaperService.updateBatchById(candidatePaperList);
        //过程表统分
        BigDecimal objectScore = this.getCandidateObjectScore(examId, candidateId, isBackup ? 1 : 0);
        iCandidateProcessService.lambdaUpdate().eq(CandidateProcess::getExamId, examId).eq(CandidateProcess::getCandidateId, candidateId).set(CandidateProcess::getObjectiveScore, objectScore).update();
    }

    private List<CandidateAnswer> getCandidateAnswerList(String examId, String candidateId, Integer isBackUp) {
        List<CandidateAnswer> candidateAnswerList = new ArrayList<CandidateAnswer>();
        if(isBackUp == 0) {
            QueryWrapper<CandidateAnswer> queryCandidateAnswer = Wrappers.query();
            queryCandidateAnswer.lambda().select(CandidateAnswer::getId, CandidateAnswer::getItemType,
                    CandidateAnswer::getItemId, CandidateAnswer::getParentItemId,
                    CandidateAnswer::getFullScore, CandidateAnswer::getStandardAnswer,
                    CandidateAnswer::getObjectiveAnswer,
                    CandidateAnswer::getSubjectiveAnswer)
                    .eq(CandidateAnswer::getExamId, examId)
                    .eq(CandidateAnswer::getCandidateId, candidateId)
                    .and(i -> i.eq(CandidateAnswer::getObjectiveOrSubjective, true).or().eq(CandidateAnswer::getItemType, PaperItemTypeCode.ITEM_TYPE_COMPOUND_CODE.getCode()))
                   // .eq(CandidateAnswer::getObjectiveOrSubjective, true)
                    .eq(CandidateAnswer::getDelFlag, false);
            candidateAnswerList = iCandidateAnswerService.list(queryCandidateAnswer);
        } else {
            LambdaQueryWrapper<CandidateAnswerBackup> query = Wrappers.lambdaQuery();
            query.select(CandidateAnswerBackup::getId, CandidateAnswerBackup::getItemType,
                    CandidateAnswerBackup::getItemId, CandidateAnswerBackup::getParentItemId,
                    CandidateAnswerBackup::getFullScore, CandidateAnswerBackup::getStandardAnswer,
                    CandidateAnswerBackup::getObjectiveAnswer)
                    .eq(CandidateAnswerBackup::getExamId, examId)
                    .eq(CandidateAnswerBackup::getCandidateId, candidateId)
                    .eq(CandidateAnswerBackup::getObjectiveOrSubjective, true)
                    .eq(CandidateAnswerBackup::getDelFlag, false);
            List<CandidateAnswerBackup> backups = iCandidateAnswerBackupService.list(query);
            for (CandidateAnswerBackup backup : backups) {
                CandidateAnswer answer = new CandidateAnswer();
                BeanUtils.copyProperties(backup,answer);
                candidateAnswerList.add(answer);
            };
        }
        return candidateAnswerList;
    }

    @Override
    public void calcObjectiveCandidateAnswerList(String examId, String candidateId, List<CandidatePaper> candidatePaperList, List<PaperDataVO> paperDataList, Integer isBackUp) {

        //获取考生答案
        List<CandidateAnswer> candidateAnswerList = this.getCandidateAnswerList(examId, candidateId, isBackUp);
        List<CandidatePaper> candidatePaperListUpdate = new ArrayList<CandidatePaper>();
        List<CandidateAnswer> candidateAnswerListUpdate = new ArrayList<CandidateAnswer>();

        for (CandidatePaper candidatePaper : candidatePaperList) {
            PaperDataVO paperData = new PaperDataVO();
            if (paperDataList != null) {
                Optional<PaperDataVO> hasPaperData = paperDataList.stream()
                        .filter(p -> p.getPaperId().equals(candidatePaper.getPaperId())
                                && candidatePaper.getPaperVersion().equals(p.getPaperVersion().toString()))
                        .findFirst();
                if(hasPaperData.isPresent()) {
                    paperData = hasPaperData.get();
                } else {
                    paperData = iExamCacheService.getPaperInfoCache(candidatePaper.getPaperId(), candidatePaper.getPaperVersion());
                }
            } else {
                paperData = iExamCacheService.getPaperInfoCache(candidatePaper.getPaperId(), candidatePaper.getPaperVersion());
            }
            for(TopicDataVO topicData : paperData.getTopicDataList()) {
                List<ItemDataVO> itemDataList = topicData.getItemDataList();
                for(ItemDataVO itemData : itemDataList){
                    if (itemData.getItemType().equals(PaperItemTypeCode.ITEM_TYPE_FILL_IN_BLANKS_CODE.getCode()) && itemData.getObjective() && StringUtils.isBlank(itemData.getItemPid())) {
                        // 统计填空题（客观题）得分
                        List<ItemAttrDTO> attrsDataList = itemData.getAttrsDataList();
                        Optional<ItemAttrDTO> attrsOutOfOrder = attrsDataList.stream().filter(a -> a.getType().equals(PaperItemAttrTypeCode.FILLINBLANKS.OUT_OF_ORDER.getCode())).findFirst();
                        Optional<ItemAttrDTO> attrsIgonreCase = attrsDataList.stream().filter(a -> a.getType().equals(PaperItemAttrTypeCode.FILLINBLANKS.IGNORE_CASE.getCode())).findFirst();
                        Boolean outOfOrder = attrsOutOfOrder.isPresent() && attrsOutOfOrder.get().getContent().equals("true");
                        Boolean igonreCase = attrsIgonreCase.isPresent() && attrsIgonreCase.get().getContent().equals("true");

                        List<CandidateAnswer> childCandidateAnswerList = candidateAnswerList.stream().filter(c -> itemData.getItemId().equals(c.getParentItemId())).collect(Collectors.toList());
                        List<OptionsDataVO>  standardItemDataList = itemData.getOptionsDataList();
                        for (CandidateAnswer childCandidateAnswer : childCandidateAnswerList) {
                            CandidateAnswer fillInBlankUpdate =  new CandidateAnswer();
                            fillInBlankUpdate.setId(childCandidateAnswer.getId());
                            fillInBlankUpdate.setPaperId(candidatePaper.getPaperId());
                            fillInBlankUpdate.setPaperVersion(candidatePaper.getPaperVersion());
                            String objectAnswer = StringUtils.isNotBlank(childCandidateAnswer.getSubjectiveAnswer()) ?  childCandidateAnswer.getSubjectiveAnswer().replaceAll(" ", "") : "";
                            objectAnswer = igonreCase ? objectAnswer.toUpperCase() : objectAnswer;
                            if (StringUtils.isBlank(objectAnswer)) {
                                fillInBlankUpdate.setScore(BigDecimal.ZERO);
                            } else if(!outOfOrder) {
                                Optional<OptionsDataVO> standardAnswerData = standardItemDataList.stream()
                                        .filter(s -> s.getOptionId().equals(childCandidateAnswer.getItemId())).findFirst();
                                String standardAnswer = standardAnswerData.isPresent() && StringUtils.isNotBlank(standardAnswerData.get().getOptionContent()) ? standardAnswerData.get().getOptionContent() : "";
                                standardAnswer = igonreCase ? standardAnswer.toUpperCase() : standardAnswer;
                                objectAnswer = igonreCase ? objectAnswer.toUpperCase() : objectAnswer;
                                BigDecimal score = standardAnswerData.isPresent() && StringUtils.isNotBlank(standardAnswerData.get().getScore())
                                        ? new BigDecimal(standardAnswerData.get().getScore()) : BigDecimal.ZERO;
                                fillInBlankUpdate.setScore(StringUtils.isNotBlank(objectAnswer) && objectAnswer.equals(standardAnswer) ? score : BigDecimal.ZERO);
                            } else {
                                //允许考生答案与参考答案顺序不一致
                                String finalObjectAnswer = objectAnswer;
                                Optional<OptionsDataVO> standardAnswerData = standardItemDataList.stream()
                                        .filter(s -> finalObjectAnswer.equals(igonreCase && StringUtils.isNotBlank(s.getOptionContent()) ? s.getOptionContent().toUpperCase() : s.getOptionContent())).findFirst();
                                if (standardAnswerData.isPresent()) {
                                    BigDecimal score = StringUtils.isNotBlank(objectAnswer) && standardAnswerData.isPresent() && StringUtils.isNotBlank(standardAnswerData.get().getScore())
                                            ? new BigDecimal(standardAnswerData.get().getScore()) : BigDecimal.ZERO;
                                    fillInBlankUpdate.setScore(score);
                                    standardItemDataList.remove(standardAnswerData.get());
                                } else {
                                    fillInBlankUpdate.setScore(BigDecimal.ZERO);
                                }
                            }
                            candidateAnswerListUpdate.add(fillInBlankUpdate);
                        }
                    } else if (itemData.getItemType().equals(PaperItemTypeCode.ITEM_TYPE_INDEFINITE_CODE.getCode())) {
                        //统计不定项选择题得分
                        Optional<CandidateAnswer> indefiniteAnswer =  candidateAnswerList.stream().filter(c -> c.getItemId().equals(itemData.getItemId())).findFirst();
                        if (indefiniteAnswer.isPresent()) {
                            CandidateAnswer indefiniteUpdate =  new CandidateAnswer();
                            indefiniteUpdate.setId(indefiniteAnswer.get().getId());
                            indefiniteUpdate.setPaperId(candidatePaper.getPaperId());
                            indefiniteUpdate.setPaperVersion(candidatePaper.getPaperVersion());
                            String standardAnswer = StringUtils.isNotBlank(itemData.getAnswer()) ?  itemData.getAnswer() : "";
                            if (StringUtils.isBlank(indefiniteAnswer.get().getObjectiveAnswer())) {
                                indefiniteUpdate.setScore(BigDecimal.ZERO);
                            } else {
                                String objectAnswer = StringUtils.isNotBlank(indefiniteAnswer.get().getObjectiveAnswer()) ?  indefiniteAnswer.get().getObjectiveAnswer() : "";
                                if (StringUtils.isNotBlank(objectAnswer) && objectAnswer.equals(standardAnswer)) {
                                    //全对得满分
                                    indefiniteUpdate.setScore(new BigDecimal(indefiniteAnswer.get().getFullScore()));
                                } else {
                                    Boolean hasErrorAnswer = false;
                                    for (String answerItem : objectAnswer.split(",")) {
                                        if(!(StringUtils.isNotBlank(objectAnswer) && standardAnswer.contains(answerItem))) {
                                            hasErrorAnswer = true;
                                            break;
                                        }
                                    }
                                    if(hasErrorAnswer) {
                                        //只要有一个错误答案，得0分
                                        indefiniteUpdate.setScore(BigDecimal.ZERO);
                                    } else {
                                        List<ItemAttrDTO> attrsDataList = itemData.getAttrsDataList();
                                        for(ItemAttrDTO attrsData : attrsDataList) {
                                            if (attrsData.getType().equals(PaperItemAttrTypeCode.INDEFINITE.OPTION_CUSTOM_SCORES.getCode()) && attrsData.getContent().equals("true")) {
                                                //选项自定义分数
                                                List<OptionsDataVO> optionsDataList = itemData.getOptionsDataList();
                                                BigDecimal score = BigDecimal.ZERO;
                                                for (OptionsDataVO optionsData : optionsDataList) {
                                                    if(StringUtils.isNotBlank(objectAnswer) && objectAnswer.contains(optionsData.getOptionName())) {
                                                        score = score.add(new BigDecimal(optionsData.getScore()));
                                                    }
                                                }
                                                indefiniteUpdate.setScore(score);
                                                break;
                                            } else if(attrsData.getType().equals(PaperItemAttrTypeCode.INDEFINITE.LESS_FIXED_STATUS.getCode()) && attrsData.getContent().equals("true")) {
                                                //少选得固定分
                                                Optional<ItemAttrDTO> attrsLessFixedScores = attrsDataList.stream().filter(a -> a.getType().equals(PaperItemAttrTypeCode.INDEFINITE.LESS_FIXED_SCORES.getCode())).findFirst();
                                                if (attrsLessFixedScores.isPresent()) {
                                                    BigDecimal score = StringUtils.isBlank(objectAnswer) || attrsLessFixedScores.get().getContent() == null ? BigDecimal.ZERO : new BigDecimal(attrsLessFixedScores.get().getContent());
                                                    indefiniteUpdate.setScore(score);
                                                } else {
                                                    indefiniteUpdate.setScore(BigDecimal.ZERO);
                                                }
                                                break;
                                            } else if(attrsData.getType().equals(PaperItemAttrTypeCode.INDEFINITE.LESS_SUM_SCORES.getCode()) && attrsData.getContent().equals("true")) {
                                                //少选得分累加
                                                Optional<ItemAttrDTO> attrsOptionCorrectScores = attrsDataList.stream().filter(a -> a.getType().equals(PaperItemAttrTypeCode.INDEFINITE.OPTION_CORRECT_SCORES.getCode())).findFirst();
                                                Optional<ItemAttrDTO> attrsSumMaxScores = attrsDataList.stream().filter(a -> a.getType().equals(PaperItemAttrTypeCode.INDEFINITE.SUM_MAX_SCORES.getCode())).findFirst();
                                                if (StringUtils.isNotBlank(objectAnswer) && attrsOptionCorrectScores.isPresent() && attrsSumMaxScores.isPresent()) {
                                                    BigDecimal optionCorrectScore = StringUtils.isNotBlank(attrsOptionCorrectScores.get().getContent()) ?  new BigDecimal(attrsOptionCorrectScores.get().getContent()) : BigDecimal.ZERO;
                                                    BigDecimal sumMaxScore = StringUtils.isNotBlank(attrsSumMaxScores.get().getContent()) ?  new BigDecimal(attrsSumMaxScores.get().getContent()) : BigDecimal.ZERO;
                                                    //选对一个得多少分乘答对几个选项
                                                    BigDecimal score =  optionCorrectScore.multiply(BigDecimal.valueOf(objectAnswer.split(",").length));
                                                    //比较是否大于设定最高得分，如果大于，取设定最高得分
                                                    score = score.compareTo(sumMaxScore) > 0 ? sumMaxScore : score;
                                                    indefiniteUpdate.setScore(score);
                                                } else {
                                                    indefiniteUpdate.setScore(BigDecimal.ZERO);
                                                }
                                                break;
                                            } else {
                                                indefiniteUpdate.setScore(BigDecimal.ZERO);
                                            }
                                        }
                                    }
                                }
                            }
                            if (StringUtils.isBlank(indefiniteAnswer.get().getStandardAnswer()) && StringUtils.isNotBlank(standardAnswer)) {
                                indefiniteUpdate.setStandardAnswer(standardAnswer);
                            }
                            candidateAnswerListUpdate.add(indefiniteUpdate);
                        }
                    }
                    else {
                        Optional<CandidateAnswer> candidateAnswer =  candidateAnswerList.stream().filter(c -> c.getItemId().equals(itemData.getItemId())).findFirst();
                        if(candidateAnswer.isPresent()) {
                            if(PaperItemTypeCode.ITEM_TYPE_COMPOUND_CODE.getCode().equals(candidateAnswer.get().getItemType())
                                    || PaperItemTypeCode.ITEM_TYPE_MATCHING_CODE.getCode().equals(candidateAnswer.get().getItemType())
                                    || PaperItemTypeCode.ITEM_TYPE_CLOZE_FILL_IN_BLANKS_CODE.getCode().equals(candidateAnswer.get().getItemType())) {
                                List<CandidateAnswer> candidateAnswerChildList = candidateAnswerList.stream().filter(c -> itemData.getItemId().equals(c.getParentItemId())).collect(Collectors.toList());
                                List<ItemDataVO> childItemList = itemData.getChildItemList();
                                for(CandidateAnswer candidateAnswerChild : candidateAnswerChildList) {
                                    Optional<ItemDataVO> childItem = childItemList.stream().filter(c -> candidateAnswerChild.getItemId().equals(c.getItemId())).findFirst();
                                    String standardAnswer = childItem.isPresent() && StringUtils.isNotBlank(childItem.get().getAnswer()) ? childItem.get().getAnswer() : "";
                                    String objectAnswer = StringUtils.isNotBlank(candidateAnswerChild.getObjectiveAnswer()) ? candidateAnswerChild.getObjectiveAnswer() : "";
                                    BigDecimal score = childItem.isPresent() && StringUtils.isNotBlank(childItem.get().getScore()) ? new BigDecimal(childItem.get().getScore()) : BigDecimal.ZERO ;
                                    BigDecimal objectScore = StringUtils.isNotBlank(objectAnswer) && objectAnswer.equals(standardAnswer) ? score : BigDecimal.ZERO;
                                    CandidateAnswer candidateAnswerUpdate =  new CandidateAnswer();
                                    candidateAnswerUpdate.setId(candidateAnswerChild.getId());
                                    candidateAnswerUpdate.setScore(objectScore);
                                    if (StringUtils.isBlank(candidateAnswerChild.getStandardAnswer()) && StringUtils.isNotBlank(standardAnswer)) {
                                        candidateAnswerUpdate.setStandardAnswer(standardAnswer);
                                    }
                                    candidateAnswerListUpdate.add(candidateAnswerUpdate);
                                }
                            }
                            else {
                                CandidateAnswer candidateAnswerUpdate =  new CandidateAnswer();
                                candidateAnswerUpdate.setId(candidateAnswer.get().getId());
                                String standardAnswer = StringUtils.isNotBlank(itemData.getAnswer()) ? itemData.getAnswer() : "";
                                String objectAnswer = StringUtils.isNotBlank(candidateAnswer.get().getObjectiveAnswer()) ? candidateAnswer.get().getObjectiveAnswer() : "";
                                BigDecimal objectScore = StringUtils.isNotBlank(objectAnswer) && objectAnswer.equals(standardAnswer) ? new BigDecimal(itemData.getScore()) : BigDecimal.ZERO;
                                candidateAnswerUpdate.setScore(objectScore);
                                if (StringUtils.isBlank(candidateAnswer.get().getStandardAnswer()) && StringUtils.isNotBlank(standardAnswer)) {
                                    candidateAnswerUpdate.setStandardAnswer(standardAnswer);
                                }
                                candidateAnswerListUpdate.add(candidateAnswerUpdate);
                            }
                        }
                    }
                }
            }
        }
        if (candidateAnswerListUpdate.size() > 0) {
            if (isBackUp == 0) {
                iCandidateAnswerService.updateBatchById(candidateAnswerListUpdate);
            } else {
                List<CandidateAnswerBackup> answers = new ArrayList<>(candidateAnswerListUpdate.size());
                candidateAnswerListUpdate.stream().forEach(e -> {
                    CandidateAnswerBackup answer = new CandidateAnswerBackup();
                    BeanUtils.copyProperties(e,answer);
                    answers.add(answer);
                });
                iCandidateAnswerBackupService.updateBatchById(answers);
            }
        }
    }

    @Override
    public BigDecimal getCandidatePaperObjectScore(String examId, String candidateId, String paperId, String paperVersion, Integer isBackUp) {
        BigDecimal candidateScore = BigDecimal.ZERO;
        if (isBackUp == 0) {
            QueryWrapper<CandidateAnswer> queryCandidateAnswer = Wrappers.query();
            queryCandidateAnswer.lambda().select(CandidateAnswer::getScore, CandidateAnswer::getId)
                    .eq(CandidateAnswer::getExamId, examId)
                    .eq(CandidateAnswer::getCandidateId, candidateId)
                    .eq(CandidateAnswer::getPaperId, paperId)
                    .eq(CandidateAnswer::getPaperVersion, paperVersion)
                    .eq(CandidateAnswer::getObjectiveOrSubjective, true)
                    .eq(CandidateAnswer::getDelFlag, false);
            List<CandidateAnswer> candidateAnswerList = iCandidateAnswerService.list(queryCandidateAnswer);
            candidateScore = candidateAnswerList.stream()
                    .map(c ->  c.getScore() == null ? BigDecimal.ZERO : c.getScore())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        } else {
            QueryWrapper<CandidateAnswerBackup> queryCandidateAnswer = Wrappers.query();
            queryCandidateAnswer.lambda().select(CandidateAnswerBackup::getScore, CandidateAnswerBackup::getId)
                    .eq(CandidateAnswerBackup::getExamId, examId)
                    .eq(CandidateAnswerBackup::getCandidateId, candidateId)
                    .eq(CandidateAnswerBackup::getPaperId, paperId)
                    .eq(CandidateAnswerBackup::getPaperVersion, paperVersion)
                    .eq(CandidateAnswerBackup::getObjectiveOrSubjective, true)
                    .eq(CandidateAnswerBackup::getDelFlag, false);
            List<CandidateAnswerBackup> candidateAnswerList = iCandidateAnswerBackupService.list(queryCandidateAnswer);
            candidateScore = candidateAnswerList.stream()
                    .map(c ->  c.getScore() == null ? BigDecimal.ZERO : c.getScore())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        return candidateScore;
    }

    @Override
    public BigDecimal getCandidateObjectScore(String examId, String candidateId, Integer isBackUp) {
        BigDecimal candidateScore = BigDecimal.ZERO;
        if (isBackUp == 0) {
            QueryWrapper<CandidateAnswer> queryCandidateAnswer = Wrappers.query();
            queryCandidateAnswer.lambda().select(CandidateAnswer::getScore, CandidateAnswer::getId)
                    .eq(CandidateAnswer::getExamId, examId)
                    .eq(CandidateAnswer::getCandidateId, candidateId)
                    .eq(CandidateAnswer::getObjectiveOrSubjective, true)
                    .eq(CandidateAnswer::getDelFlag, false);
            List<CandidateAnswer> candidateAnswerList = iCandidateAnswerService.list(queryCandidateAnswer);
            candidateScore = candidateAnswerList.stream()
                    .map(c ->  c.getScore() == null ? BigDecimal.ZERO : c.getScore())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        } else {
            QueryWrapper<CandidateAnswerBackup> queryCandidateAnswer = Wrappers.query();
            queryCandidateAnswer.lambda().select(CandidateAnswerBackup::getScore, CandidateAnswerBackup::getId)
                    .eq(CandidateAnswerBackup::getExamId, examId)
                    .eq(CandidateAnswerBackup::getCandidateId, candidateId)
                    .eq(CandidateAnswerBackup::getObjectiveOrSubjective, true)
                    .eq(CandidateAnswerBackup::getDelFlag, false);
            List<CandidateAnswerBackup> candidateAnswerList = iCandidateAnswerBackupService.list(queryCandidateAnswer);
            candidateScore = candidateAnswerList.stream()
                    .map(c ->  c.getScore() == null ? BigDecimal.ZERO : c.getScore())
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
        }

        return candidateScore;
    }
}
